package fina2.upload;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.jboss.seam.Component;
import org.jboss.seam.log.Log;
import org.jboss.seam.log.Logging;
import org.jboss.seam.servlet.ContextualHttpServletRequest;

import fina2.dcs.common.util.FileUtil;
import fina2.dcs.security.User;
import fina2.dcs.security.UserLocal;
import fina2.dcs.system.SysProperty;
import fina2.dcs.system.SysPropertyLocal;
import fina2.dcs.upload.UploadedFileLocal;
import fina2.dcs.upload.UploadedFileType;

@SuppressWarnings({ "unchecked", "serial" })
public class UploadServlet extends HttpServlet {

	private Log log = Logging.getLog(getClass());

	private UploadBean ub = null;

	private void wrappedPost(HttpServletRequest req, HttpServletResponse res) {
		log.info("Trying to upload");
		Map<String, byte[]> filesToUpload = new ConcurrentHashMap<String, byte[]>();
		try {
			UserLocal usrLocal = null;

			UploadedFileLocal uploadFileLocal = null;
			InitialContext ic = new InitialContext();

			uploadFileLocal = (UploadedFileLocal) ic.lookup("UploadedFileSession/local");
			ub = (UploadBean) Component.getInstance("uploadBean");
			usrLocal = (UserLocal) ic.lookup("UserSession/local");
			// UserLocal us = (UserLocal) Component.getInstance("userSession");

			// Create a factory for disk-based file items
			DiskFileItemFactory factory = new DiskFileItemFactory(1024 * 1024, new File(System.getProperty("java.io.tmpdir")));

			// Create a new file upload handler
			ServletFileUpload upload = new ServletFileUpload(factory);

			// Parse the request
			List<FileItem> items = (List<FileItem>) upload.parseRequest(req);

			Iterator<FileItem> iter = items.iterator();

			while (iter.hasNext()) {
				FileItem item = iter.next();

				if (!item.isFormField()) {

					String fileName = item.getName();
					String contentType = item.getContentType();
					boolean isInMemory = item.isInMemory();
					long sizeInBytes = item.getSize();

					if (fileName.toLowerCase().trim().indexOf(UploadedFileType.XML.getExtension()) != -1) {
						copyXml(fileName, item.get());
					} else if (fileName.toLowerCase().trim().indexOf(UploadedFileType.XLS.getExtension()) != -1) {
						filesToUpload.put(fileName, item.get());
					} else if (fileName.toLowerCase().trim().indexOf(UploadedFileType.ZIP.getExtension()) != -1) {
						FileUtil fu = new FileUtil();
						try {
							fu.readFromZip(item.getName(), filesToUpload, item.get());
						} catch (IllegalArgumentException ex) {
                             log.error(ex.getMessage(), ex);
						}
					}

					log.info("********Proceeding file********");
					log.info("FileName " + fileName);
					log.info("ContentType " + contentType);
					log.info("Is In Memory " + isInMemory);
					log.info("Size In Bytes " + sizeInBytes);
					log.info("********File proceeded********");

					item.delete();
				}
			}

			User u = usrLocal.getCurrentUser();

			uploadFileLocal.upload(filesToUpload, u, null);

			uploadFileLocal.loadUploadedFiles(ub.getUploadedFile());

			items.clear();
			res.sendRedirect("/fina-dcs-wp/security/data.seam");
		} catch (IOException ioex) {
			log.error(ioex.getMessage(), ioex);
		} catch (Exception ex) {
			try {
				res.sendRedirect("/fina-dcs-wp/security/uploadError.html");
			} catch (Exception e) {
				log.error(e.getMessage(), e);
			}
			log.error(ex.getMessage(), ex);
		} finally {
			filesToUpload.clear();
		}

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		final HttpServletRequest req = request;
		final HttpServletResponse res = response;
		new ContextualHttpServletRequest(req) {
			public void process() throws Exception {
				wrappedPost(req, res);
			}

		}.run();

	}

	private void copyXml(String fileName, byte[] content) {
		String location = null;
		log.info("Copying XML " + fileName);
		try {
			SysPropertyLocal sysPropLocal = (SysPropertyLocal) Component.getInstance("propSession");
			SysProperty sysProp = sysPropLocal.findProperty("fina2.converted.xmls");
			location = (sysProp != null) ? (sysProp.getValue() + "\\") : "C:\\fina-server\\";
			File f = new File(location + fileName);
			FileOutputStream fos = new FileOutputStream(f);
			fos.write(content);
			fos.close();
			log.info("XML " + fileName + " Copied");
		} catch (Exception ex) {
			log.error("Error During Copying Xml to location " + location);
			log.error(ex.getMessage(), ex);
		}
	}

	
}
